package com.leo.chapter07;

import java.math.BigInteger;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 当生产者生产速度大于消费者，队列将会填满，put方法会阻塞。
 * 此时，如果消费者希望生产者取消任务，生产者将会在put一直阻塞下去，不会取消了
 * @author xuexiaolei
 * @version 2017年10月16日
 */
public class BrokenPrimeProducer extends Thread {
    private final BlockingQueue<BigInteger> queue;
    private volatile boolean cancelled = false;//记录取消状态

    public BrokenPrimeProducer(BlockingQueue<BigInteger> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            BigInteger p = BigInteger.ONE;
            while (!cancelled){
                p = p.nextProbablePrime();
                queue.put(p);//阻塞方法，注意
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void cancell(){ cancelled = true; }

    /**
     * 消费生产者
     * @throws InterruptedException
     */
    void consumePrimes() throws InterruptedException{
        BlockingQueue<BigInteger> primes = new ArrayBlockingQueue<BigInteger>(10);
        BrokenPrimeProducer producer = new BrokenPrimeProducer(primes);
        producer.start();
        try {
            while (needMorePrimes()){
                consume(primes.take());
            }
        }finally {
            producer.cancell();
        }
    }

    private void consume(BigInteger take) { }

    private boolean needMorePrimes() { return true;}
}
